package com.tonicgb.shared.exception;

import com.tonicgb.shared.common.response.Result;
import org.slf4j.Logger;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import static org.slf4j.LoggerFactory.*;
/**
 * @author zhaiyujin
 * @date 2021-09-01 14:09:07
 * @说明 全局异常
 */
@RestControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
    private static Logger LOGGER = getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler
    public Result processException(Exception ex, HttpServletRequest request, HttpServletResponse response){
       // ex.printStackTrace(); 错误打印控制台

        Result result = Result.error(ex.getMessage());

            if (ex instanceof BindException) {
                result = validationErrorResult(((BindException) ex).getBindingResult());
                LOGGER.error("validation: "+result.getMessage()+"");
            } else if (ex instanceof ConstraintViolationException) {
                result = validationErrorResult((ConstraintViolationException) ex);
                LOGGER.error("validation: "+result.getMessage()+"");
            } else if (ex instanceof MethodArgumentNotValidException) {
                result = validationErrorResult(((MethodArgumentNotValidException) ex).getBindingResult());
                LOGGER.error("validation: "+result.getMessage()+"");
            } else if (ex instanceof ApiException) {
                ApiException apiException = (ApiException) ex;
                if (apiException.getErrorCode() == 1) {
                    result = Result.error(Result.ERROR, apiException.getMessage());
                } else {
                    result = Result.error(apiException.getErrorCode(), apiException.getMessage());
                }
                 LOGGER.error("======="+ex.getMessage()+"=======");
            } else {
                result = Result.error(Result.ERROR, Result.SYSTEM_BUSSY);
                LOGGER.error("======="+ex.getMessage()+"=======");
            }

        return result;

    }

        private Result validationErrorResult(ConstraintViolationException exception) {
            ConstraintViolation<?> constraintViolation = exception.getConstraintViolations().stream().findFirst().orElse(null);
            if (constraintViolation != null) {
                return Result.error(Result.VALIDATE_ERROR, constraintViolation.getMessage());
            }
//                .stream()
//                .map(ConstraintViolation::getMessage)
//                .collect(Collectors.joining(","));
            return Result.error(Result.VALIDATE_ERROR, "");
        }
        private Result validationErrorResult(BindingResult bindingResult) {
            String message = bindingResult.getAllErrors().get(0).getDefaultMessage();
//                .stream()
//                .map(DefaultMessageSourceResolvable::getDefaultMessage)
//                .collect(Collectors.joining(","));
            return Result.error(Result.VALIDATE_ERROR, message);
        }

}
